﻿using System;
using System.Collections.Generic;

namespace Hanhud.Security
{
    public class CMembershipUser
    {
        public class CProfile
        {
            public string FullName { get; set; }
            public string Company { get; set; }
            public string Email { get; set; }
            public string Address { get; set; }
            public string WorkPhone { get; set; }
            public string HandPhone { get; set; }
            public string Fax { get; set; }
            private CLocation _location = null;
            public CLocation Location { get { return _location; } set { _location = value; } }

            public CProfile(string fullName, string company, string email, string address, int provinceCode, int districtCode, int communeCode, string workPhone, string handPhone, string fax)
            {
                this.FullName = fullName;
                this.Company = company;
                this.Email = email;
                this.Address = address;
                this.WorkPhone = workPhone;
                this.HandPhone = handPhone;
                this.Fax = fax;
                this.Location = CLocation.GetLocationInfo(provinceCode, districtCode, communeCode);
            }

            internal CProfile()
            {
            }
        }

        private string[] _roles = null;

        #region Properties
        public string ActivationCode { get; set; }
        public Guid UserID { get; protected set; }
        public string UserName { get; set; }
        public DateTime CreatedDate { get; set; }
        public string Email { get; set; }
        public bool IsApproved { get; set; }
        public bool IsLockedOut { get; set; }
        public bool IsOnline { get; protected set; }
        public bool IsAuthenticated { get; set; }
        public DateTime LastActivityDate { get; set; }
        public DateTime LastLockedOutDate { get; protected set; }
        public DateTime LastLoginDate { get; set; }
        public DateTime LastPasswordChangedDate { get; set; }
        public string PasswordQuestion { get; protected set; }
        public CProfile Profile { get; set; }
        #endregion

        #region Constructors
        public CMembershipUser(string activationCode, Guid userID, string email, string passwordQuestion, bool isApproved, bool isLockedOut,
            DateTime createdDate, DateTime lastLoginDate, DateTime lastActivityDate, DateTime lastPasswordChangedDate, DateTime lastLockedOutDate, bool userIsOnline)
        {
            this.ActivationCode = activationCode;
            this.UserID = userID;
            this.Email = email;
            this.PasswordQuestion = passwordQuestion;
            this.IsApproved = isApproved;
            this.IsLockedOut = isLockedOut;
            this.CreatedDate = createdDate;
            this.LastLoginDate = lastLoginDate;
            this.LastActivityDate = lastActivityDate;
            this.LastPasswordChangedDate = lastPasswordChangedDate;
            this.LastLockedOutDate = lastLockedOutDate;
            if (userIsOnline)
                this.IsAuthenticated = true;
            this._roles = null;
        }

        public CMembershipUser(string activationCode, Guid userID, string email, string passwordQuestion, bool isApproved, bool isLockedOut,
            DateTime createdDate, DateTime lastLoginDate, DateTime lastActivityDate, DateTime lastPasswordChangedDate, DateTime lastLockedOutDate)
        {
            this.ActivationCode = activationCode;
            this.UserID = userID;
            this.Email = email;
            this.PasswordQuestion = passwordQuestion;
            this.IsApproved = isApproved;
            this.IsLockedOut = isLockedOut;
            this.CreatedDate = createdDate;
            this.LastLoginDate = lastLoginDate;
            this.LastActivityDate = lastActivityDate;
            this.LastPasswordChangedDate = lastPasswordChangedDate;
            this.LastLockedOutDate = lastLockedOutDate;
            this.IsAuthenticated = false;
            this._roles = null;
        }
        public CMembershipUser()
        {
            this.IsOnline = true;
            this._roles = null;
            this.IsAuthenticated = false;
            this.Profile = new CProfile();
        }
        #endregion

        public string[] Roles
        {
            get
            {
                if (_roles == null || (_roles != null && _roles.Length == 0))
                {
                    // Gets a list of the roles that a specified user is in
                    _roles = CRole.GetRolesForUser(this.UserName);
                }

                return _roles;
            }
        }
        // Summary:
        //     Updates the password for the membership user in the membership data store.
        //
        // Parameters:
        //   oldPassword:
        //     The current password for the membership user.
        //
        //   newPassword:
        //     The new password for the membership user.
        //
        // Returns:
        //     true if the update was successful; otherwise, false.
        //
        // Exceptions:
        //   System.ArgumentException:
        //     oldPassword is an empty string.  -or- newPassword is an empty string.
        //
        //   System.ArgumentNullException:
        //     oldPassword is null.  -or- newPassword is null.
        public virtual bool ChangePassword(string oldPassword, string newPassword)
        {
            return CMembership.ChangePassword(this.UserName, oldPassword, newPassword);
        }
        //
        // Summary:
        //     Updates the password question and answer for the membership user in the membership
        //     data store.
        //
        // Parameters:
        //   password:
        //     The current password for the membership user.
        //
        //   newPasswordQuestion:
        //     The new password question value for the membership user.
        //
        //   newPasswordAnswer:
        //     The new password answer value for the membership user.
        //
        // Returns:
        //     true if the update was successful; otherwise, false.
        //
        // Exceptions:
        //   System.ArgumentException:
        //     password is an empty string.  -or- newPasswordQuestion is an empty string.
        //      -or- newPasswordAnswer is an empty string.
        //
        //   System.ArgumentNullException:
        //     password is null.
        public virtual bool ChangePasswordQuestionAndAnswer(string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            return CMembership.ChangePasswordQuestionAndAnswer(this.UserName, password, newPasswordQuestion, newPasswordAnswer);
        }
        //
        // Summary:
        //     Gets the password for the membership user from the membership data store.
        //
        // Returns:
        //     The password for the membership user.
        public virtual string GetPassword()
        {
            return string.Empty;
        }
        //
        // Summary:
        //     Gets the password for the membership user from the membership data store.
        //
        // Parameters:
        //   passwordAnswer:
        //     The password answer for the membership user.
        //
        // Returns:
        //     The password for the membership user.
        public virtual string GetPassword(string passwordAnswer)
        {
            return string.Empty;
        }
        //
        // Summary:
        //     Resets a user's password to a new, automatically generated password.
        //
        // Returns:
        //     The new password for the membership user.
        public virtual string ResetPassword()
        {
            return ResetPassword(string.Empty);
        }
        //
        // Summary:
        //     Resets a user's password to a new, automatically generated password.
        //
        // Parameters:
        //   passwordAnswer:
        //     The password answer for the membership user.
        //
        // Returns:
        //     The new password for the membership user.
        public virtual string ResetPassword(string passwordAnswer)
        {
            return CMembership.ResetPassword(this.UserName, passwordAnswer);
        }
        //
        // Summary:
        //     Returns the user name for the membership user.
        //
        // Returns:
        //     The System.Web.Security.MembershipUser.UserName for the membership user.
        public override string ToString()
        {
            return string.Empty;
        }
        //
        // Summary:
        //     Clears the locked-out state of the user so that the membership user can be
        //     validated.
        //
        // Returns:
        //     true if the membership user was successfully unlocked; otherwise, false.
        public virtual bool UnlockUser()
        {
            return CMembership.UnlockUser(this.UserName);
        }

        public bool IsCorrectPassword(string password)
        {
            throw new NotImplementedException();
        }

        public void LogInAs(CMembershipUser user)
        {
            this.UserID = user.UserID;
            this.UserName = user.UserName;
            this.ActivationCode = user.ActivationCode;
            this._roles = this.Roles;
            this.Profile = user.Profile;
            this.IsLockedOut = user.IsLockedOut;
            this.LastActivityDate = user.LastActivityDate;
            this.LastLockedOutDate = user.LastLockedOutDate;
            this.LastLoginDate = user.LastLoginDate;
            this.LastPasswordChangedDate = user.LastPasswordChangedDate;
            this.PasswordQuestion = user.PasswordQuestion;

            this.IsAuthenticated = true;
            this.IsOnline = true;
        }

        public void LogOut()
        {
            this.IsAuthenticated = false;
            this.IsOnline = false;
        }

        public bool UpdateProfile()
        {
            throw new NotImplementedException();
        }
    }

    public class CMembershipUserCollection : IEnumerable<CMembershipUser>
    {
        class CUserEnumerator : IEnumerator<CMembershipUser>
        {
            private CMembershipUserCollection _userCollection;
            private int _position;

            public CUserEnumerator(CMembershipUserCollection userCollection)
            {
                _userCollection = userCollection;
                _position = -1;
            }

            #region IEnumerator<CMembershipUser> Members

            public CMembershipUser Current
            {
                get
                {
                    if (_position == -1 || _position >= _userCollection._users.Length)
                        throw new InvalidOperationException("Index out of range");
                    return _userCollection._users[_position];
                }
            }

            #endregion

            #region IDisposable Members

            public void Dispose()
            {

            }

            #endregion

            #region IEnumerator Members

            object System.Collections.IEnumerator.Current
            {
                get
                {
                    if (_position == -1 || _position >= _userCollection._users.Length)
                        throw new InvalidOperationException("Index out of range");
                    return _userCollection._users[_position];
                }
            }

            public bool MoveNext()
            {
                _position++;
                return _position >= _userCollection._users.Length ? false : true;
            }

            public void Reset()
            {
                _position = -1;
            }

            #endregion
        }
        private CMembershipUser[] _users;

        public CMembershipUserCollection(CMembershipUser[] users)
        {
            _users = new CMembershipUser[users.Length];
            for (int i = 0; i < users.Length; i++)
                _users[i] = users[i];
        }
        public int Count
        {
            get
            {
                return _users.Length;
            }
        }

        #region IEnumerable<CMembershipUser> Members

        IEnumerator<CMembershipUser> IEnumerable<CMembershipUser>.GetEnumerator()
        {
            return new CUserEnumerator(this);
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return new CUserEnumerator(this);
        }

        #endregion
    }
}
